# -*- coding: utf-8 -*-
# +
from copy import deepcopy
import sys,os
basePath = os.path.split(os.path.realpath(__file__))[0]
sys.path.append(basePath)
import numpy as np

from functions import *

class CONFIG:
    instance_ = None
    def __new__(cls, *args, **kwargs):
        if cls.instance_ is None:
            cls.instance_ = object.__new__(cls, *args, **kwargs)
        return cls.instance_

    def __init__(self):
        # 所有场站及文件位置
        self.STATIONS = ['A', 'B', 'C', 'A1', 'A2', 'A3']
        cur_dir = os.path.split(os.path.realpath(__file__))[0]
        dataset_path = os.path.join(cur_dir, '../../dataset')
        files = [os.path.join(dataset_path, i) for i in os.listdir(dataset_path) if '附件' in i]
        self.FILE_DICT = {'A':files[0], 'B':files[1], 'C':files[1], 
            'A1':files[2], 'A2':files[2], 'A3':files[2]}
        self.NEW_DATASET_PATH = os.path.join(dataset_path, 'csv_split_dataset')
        ensure_folder(self.NEW_DATASET_PATH)
        self.GOOD_DATASET_PATH = os.path.join(dataset_path, 'csv_good_dataset')
        ensure_folder(self.GOOD_DATASET_PATH)
        self.MERGED_DATASET_PATH = os.path.join(dataset_path, 'csv_merged_dataset')
        ensure_folder(self.MERGED_DATASET_PATH)
        self.MERGED_DATASET_PATH_ZSCORE = os.path.join(dataset_path, 'csv_merged_dataset_zscore')
        ensure_folder(self.MERGED_DATASET_PATH_ZSCORE)
        self.MERGED_DATASET_PATH_ZSCORE2 = os.path.join(dataset_path, 'csv_merged_dataset_zscore2')
        ensure_folder(self.MERGED_DATASET_PATH_ZSCORE2)
        self.IAQI_DATASET_PATH = os.path.join(dataset_path, 'IAQI_dataset')
        ensure_folder(self.IAQI_DATASET_PATH)
        self.DATASET_FIGURES_PATH = os.path.join(dataset_path, 'dataset_figures')
        ensure_folder(self.DATASET_FIGURES_PATH)
        self.MODEL_ROOT = os.path.join(cur_dir, '../../mycode/models/')
        
        # 原始一次预报数据特征（所有场站相同）
        self.YB_FEATURES = {}
        self.YB_FEATURES['TXT'] = ['模型运行日期', '预测时间', '地点']
        for station in self.STATIONS:
            self.YB_FEATURES[station] = ['近地2米温度（℃）', '地表温度（K）', '比湿（kg/kg）',
                '湿度（%）', '近地10米风速（m/s）', '近地10米风向（°）', '雨量（mm）', '云量', '边界层高度（m）', '大气压（Kpa）', 
                '感热通量（W/m²）', '潜热通量（W/m²）', '长波辐射（W/m²）', '短波辐射（W/m²）', '地面太阳能辐射（W/m²）', 
                'SO2小时平均浓度(μg/m³)', 'NO2小时平均浓度(μg/m³)', 'PM10小时平均浓度(μg/m³)', 'PM2.5小时平均浓度(μg/m³)',
                'O3小时平均浓度(μg/m³)', 'CO小时平均浓度(mg/m³)']

        # 原始实测数据特征（每个场站名称及特征数量有差异）
        self.SC_FEATURES = {}
        self.SC_FEATURES['TXT'] = ['监测时间', '地点']
        self.SC_FEATURES['A'] = ['SO2监测浓度(μg/m³)', 'NO2监测浓度(μg/m³)', 'PM10监测浓度(μg/m³)',
            'PM2.5监测浓度(μg/m³)', 'O3监测浓度(μg/m³)', 'CO监测浓度(mg/m³)', '温度(℃)', '湿度(%)', '气压(MBar)', '风速(m/s)', '风向(°)']
        self.SC_FEATURES['B'] = ['SO2监测浓度(μg/m³)', 'NO2监测浓度(μg/m³)', 'PM10监测浓度(μg/m³)',
            'PM2.5监测浓度(μg/m³)', 'O3监测浓度(μg/m³)', 'CO监测浓度(mg/m³)', '温度(℃)', '湿度(%)', '气压(MBar)', '近地风速(m/s)', '风向(°)']
        self.SC_FEATURES['C'] = ['SO2监测浓度(μg/m³)', 'NO2监测浓度(μg/m³)', 'PM10监测浓度(μg/m³)',
            'PM2.5监测浓度(μg/m³)', 'O3监测浓度(μg/m³)', 'CO监测浓度(mg/m³)', '温度(℃)', '湿度(%)', '大气压(mBar)', '风速(m/s)', '风向(°)']
        self.SC_FEATURES['A1'] = ['SO2监测浓度(μg/m³)', 'NO2监测浓度(μg/m³)', 'PM10监测浓度(μg/m³)',
            'PM2.5监测浓度(μg/m³)', 'O3监测浓度(μg/m³)', 'CO监测浓度(mg/m³)', '温度(℃)', '湿度(%)', '近地风速(m/s)', '风向(°)']
        self.SC_FEATURES['A2'] = deepcopy(self.SC_FEATURES['B'])
        self.SC_FEATURES['A3'] = deepcopy(self.SC_FEATURES['B'])
        
        
        self.RENAME_DICT = {'SO2监测浓度(μg/m³)':'SO2_', 'NO2监测浓度(μg/m³)':'NO2_', 'PM10监测浓度(μg/m³)':'PM10_',
                            'PM2.5监测浓度(μg/m³)':'PM2.5_', 'O3监测浓度(μg/m³)':'O3_', 'CO监测浓度(mg/m³)':'CO_', 
                            
                            '温度(℃)':'T', '湿度(%)':'WET', '气压(MBar)':'P', '风速(m/s)':'WIND', '风向(°)':'WIND_DIR', '近地风速(m/s)':'WIND','大气压(mBar)':'P',
                           '近地2米温度（℃）':'T', '地表温度（K）':'GROUND_T', '比湿（kg/kg）':'PER_WET','湿度（%）':'WET', 
                            '近地10米风速（m/s）':'WIND', '近地10米风向（°）':'WIND_DIR', '雨量（mm）':'RAIN', '云量':'CLOUD', 
                            '边界层高度（m）':'HEIGHT', '大气压（Kpa）':'P', '感热通量（W/m²）':'SENSE_HOT', 
                            '潜热通量（W/m²）':'LATENT_HOT', '长波辐射（W/m²）':'LONG_RAY', '短波辐射（W/m²）':'SHORT_RAY', 
                            '地面太阳能辐射（W/m²）':'GROUND_RAY', 'SO2小时平均浓度(μg/m³)':'SO2', 'NO2小时平均浓度(μg/m³)':'NO2', 
                            'PM10小时平均浓度(μg/m³)':'PM10', 'PM2.5小时平均浓度(μg/m³)':'PM2.5','O3小时平均浓度(μg/m³)':'O3', 
                            'CO小时平均浓度(mg/m³)':'CO',
                            
                           'O3最大八小时滑动平均监测浓度(μg/m³)':'O3_', 'CO实测日均(mg/m³)':'CO_', 'SO2实测日均(μg/m³)':'SO2_',
                            'NO2实测日均(μg/m³)':'NO2_', 'O3实测八小时滑动平均日最大值(μg/m³)':'O3_','PM10实测日均(μg/m³)':'PM10_',
                            'PM2.5实测日均(μg/m³)':'PM2.5_',
                           }
        self.FEATURES = ['T', 'WET', 'P', 'WIND', 'WIND_DIR', 'WIND', 'RAIN','GROUND_T', 'CLOUD', 'HEIGHT', 'P', 'SENSE_HOT', 'LATENT_HOT', 'LONG_RAY',
                        'SHORT_RAY', 'GROUND_RAY','PER_WET', 'SO2', 'NO2', 'PM10', 'PM2.5', 'O3', 'CO', 'date_sub']
        self.LABELS = ['SO2_', 'NO2_', 'PM10_', 'PM2.5_', 'O3_', 'CO_']
        
        # AQI参数
        self.IAQI_LIMIT = [0, 50, 100, 150, 200, 300, 400, 500] #空气质量分指数（IAQI）
        self.AQI_LIMIT = {}
        self.AQI_LIMIT['CO监测浓度(mg/m³)'] = [0, 2, 4, 14, 24, 36, 48, 60] #一氧化碳（CO）24小时平均
        self.AQI_LIMIT['SO2监测浓度(μg/m³)'] = [0, 50, 150, 475, 800, 1600, 2100, 2620] #二氧化硫（SO2）24小时平均
        self.AQI_LIMIT['NO2监测浓度(μg/m³)'] = [0, 40, 80, 180, 280, 565, 750, 940] #二氧化氮（NO2）24小时平均
        self.AQI_LIMIT['O3最大八小时滑动平均监测浓度(μg/m³)'] = [0, 100, 160, 215, 265, 800, 9999, 9999] #臭氧（O3）最大8小时滑动平均
        self.AQI_LIMIT['PM10监测浓度(μg/m³)'] = [0, 50, 150, 250, 350, 420, 500, 600] #粒径小于等于10μm颗粒物（PM10）24小时平均
        self.AQI_LIMIT['PM2.5监测浓度(μg/m³)'] = [0, 35, 75, 115, 150, 250, 350, 500] #粒径小于等于2.5μm颗粒物（PM2.5）24小时平均
        self.AQI_NAME_C = {'CO监测浓度(mg/m³)':'CO实测日均(mg/m³)','SO2监测浓度(μg/m³)':'SO2实测日均(μg/m³)',
                           'NO2监测浓度(μg/m³)':'NO2实测日均(μg/m³)',
                           'O3最大八小时滑动平均监测浓度(μg/m³)':'O3实测八小时滑动平均日最大值(μg/m³)',
                           'PM10监测浓度(μg/m³)':'PM10实测日均(μg/m³)','PM2.5监测浓度(μg/m³)':'PM2.5实测日均(μg/m³)'}
        self.AQI_LIMIT['CO_'] = [0, 2, 4, 14, 24, 36, 48, 60] #一氧化碳（CO）24小时平均
        self.AQI_LIMIT['SO2_'] = [0, 50, 150, 475, 800, 1600, 2100, 2620] #二氧化硫（SO2）24小时平均
        self.AQI_LIMIT['NO2_'] = [0, 40, 80, 180, 280, 565, 750, 940] #二氧化氮（NO2）24小时平均
        self.AQI_LIMIT['O3_'] = [0, 100, 160, 215, 265, 800, 9999, 9999] #臭氧（O3）最大8小时滑动平均
        self.AQI_LIMIT['PM10_'] = [0, 50, 150, 250, 350, 420, 500, 600] #粒径小于等于10μm颗粒物（PM10）24小时平均
        self.AQI_LIMIT['PM2.5_'] = [0, 35, 75, 115, 150, 250, 350, 500] #粒径小于等于2.5μm颗粒物（PM2.5）24小时平均
        # 数据过滤日期
        self.DATASET_FILT_PARAMS = {'date_sub':1, 'to_delete_qb_ranges':[]}
        self.EXAM_DATES = ['2021-7-10 00:00:00']
        
        # 正常特征范围
        self.YB_RANGE = {}
        for station in self.STATIONS:
            self.YB_RANGE[station] = {fea:[-np.inf, np.inf] for fea in self.YB_FEATURES[station]}
        self.SC_RANGE = {}
        for station in self.STATIONS:
            self.SC_RANGE[station] = {fea:[-np.inf, np.inf] for fea in self.SC_FEATURES[station]}
            
        # xgb参数
        self.PARAMS = {
            'objective': 'reg:squarederror', 
            'base_score': 0.5, 
            'booster': 'gbtree', 
            'colsample_bylevel': 1, 
            'colsample_bynode': 1, 
            'colsample_bytree': 1,#0.956, 
            'gamma': 0.1,#0.0171, 
            'gpu_id': -1, 
            'importance_type': 'gain', 
            'interaction_constraints': '', 
            'learning_rate': 0.03, 
            'max_delta_step': 0, 
            'max_depth': 6, 
            'min_child_weight': 0.01,#0.2312, 
            'missing': np.nan, 
            'monotone_constraints': '()', 
            'n_estimators': 300, 
            'n_jobs': 8 if multiprocessing.cpu_count() > 30 else 1, 
            'num_parallel_tree': 1, 
            'random_state': 0, 
            'reg_alpha': 0, 
            'reg_lambda': 1, 
            'scale_pos_weight': 1, 
            'subsample': 1,#0.895, 
            'tree_method': 'hist', 
            'validate_parameters': 1, 
            'verbosity': 0, 
            'seed': 0}
        self.PARAMS_DICT = {station:deepcopy(self.PARAMS) for station in self.STATIONS}
        
        
        
        
        
        




